﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ucKeyb
{
    /// <summary>
    /// Interaction logic for Keyboard.xaml
    /// </summary>
    public partial class Keyboard : UserControl
    {
        private TextBox controlToWriteToo;
        public bool shift { get; private set; }
        private string strKeys1 = "q\\w\\e\\r\\t\\y\\u\\i\\o\\p\\å";
        private string strKeys2 = "a\\s\\d\\f\\g\\h\\j\\k\\l\\æ\\ø";
        private string strKeys3 = "z\\x\\c\\v\\b\\n\\m";
        private List<string> keys1;
        private List<string> keys2;
        private List<string> keys3;

        private TextBlock txblShift;
        private TextBlock txblCroc;
        private TextBlock txblComma;
        private TextBlock txblDot;
        private TextBlock txblStroke;
        private TextBlock txblSpace;
        private TextBlock txblDelete;
        public Keyboard()
        {
            keys1 = new List<string>();
            foreach (string str in strKeys1.Split('\\'))
                keys1.Add(str);
            keys2 = new List<string>();
            foreach (string str in strKeys2.Split('\\'))
                keys2.Add(str);
            keys3 = new List<string>();
            foreach (string str in strKeys3.Split('\\'))
                keys3.Add(str);
            controlToWriteToo = new TextBox();
            InitializeComponent();
            initKeys();
        }

        public TextBox ControlToWriteToo
        {
            get 
            { 
                return controlToWriteToo; 
            }
            set 
            {
                if (controlToWriteToo != null)
                {
                    controlToWriteToo.Background = new SolidColorBrush(Colors.White);
                }
                controlToWriteToo = value;
                controlToWriteToo.Background = new SolidColorBrush(Colors.LightCyan);
            }
        }

        public void toogleShift()
        {
            if (shift)
                shift = false;
            else
                shift = true;
            initKeys();
        }

        private void initKeys()
        {
            wrpChars1.Children.Clear();
            wrpChars2.Children.Clear();
            wrpChars3.Children.Clear();
            grdNum.Children.Clear();
            grdNum.RowDefinitions.Clear();
            wrpSpaceDel.Children.Clear();

            Label lblSpacer = new Label();
            lblSpacer.Width = 180;
            wrpSpaceDel.Children.Add(lblSpacer);

            Border brd = new Border();
            txblSpace = new TextBlock();
            txblSpace.Text = " ";
            setupTextBlockProps(txblSpace);
            setupBorderProps(brd);
            Grid g = new Grid();
            setupGridProps(g);
            g.Width = 300;
            g.Children.Add(txblSpace);
            brd.Child = g;
            brd.Width = 300;
            txblSpace.Height = 40;
            wrpSpaceDel.Children.Add(brd);

            brd = new Border();
            txblDelete = new TextBlock();
            txblDelete.Text = "Delete";
            setupTextBlockProps(txblDelete);
            setupBorderProps(brd);
            g = new Grid();
            setupGridProps(g);
            g.Children.Add(txblDelete);
            g.Width = 70;
            brd.Child = g;
            txblDelete.Height = 40;
            brd.Width = 70;
            txblDelete.FontSize = 20;
            wrpSpaceDel.Children.Add(brd);

            if (shift)
            {
                foreach (string str in keys1)
                {
                    brd = new Border();
                    TextBlock txbl = new TextBlock();
                    txbl.Text = str.ToUpper();
                    setupTextBlockProps(txbl);
                    setupBorderProps(brd);
                    g = new Grid();
                    setupGridProps(g);
                    g.Children.Add(txbl);
                    brd.Child = g;
                    wrpChars1.Children.Add(brd);
                }

                brd = new Border();
                txblShift = new TextBlock();
                txblShift.Text = "^";
                setupTextBlockProps(txblShift);
                setupBorderProps(brd);
                g = new Grid();
                setupGridProps(g);
                g.Children.Add(txblShift);
                brd.Child = g;
                wrpChars2.Children.Add(brd);
                foreach (string str in keys2)
                {
                    brd = new Border();
                    TextBlock txbl = new TextBlock();
                    txbl.Text = str.ToUpper();
                    setupTextBlockProps(txbl);
                    setupBorderProps(brd);
                    g = new Grid();
                    setupGridProps(g);
                    g.Children.Add(txbl);
                    brd.Child = g;
                    wrpChars2.Children.Add(brd);
                }

                brd = new Border();
                txblCroc = new TextBlock();
                txblCroc.Text = ">";
                setupTextBlockProps(txblCroc);
                setupBorderProps(brd);
                g = new Grid();
                setupGridProps(g);
                g.Children.Add(txblCroc);
                brd.Child = g;
                wrpChars3.Children.Add(brd);
                foreach (string str in keys3)
                {
                    brd = new Border();
                    TextBlock txbl = new TextBlock();
                    txbl.Text = str.ToUpper();
                    setupTextBlockProps(txbl);
                    setupBorderProps(brd);
                    g = new Grid();
                    setupGridProps(g);
                    g.Children.Add(txbl);
                    brd.Child = g;
                    wrpChars3.Children.Add(brd);
                }
                brd = new Border();
                txblComma = new TextBlock();
                txblComma.Text = ";";
                setupTextBlockProps(txblComma);
                setupBorderProps(brd);
                g = new Grid();
                setupGridProps(g);
                g.Children.Add(txblComma);
                brd.Child = g;
                wrpChars3.Children.Add(brd);

                brd = new Border();
                txblDot = new TextBlock();
                txblDot.Text = ":";
                setupTextBlockProps(txblDot);
                setupBorderProps(brd);
                g = new Grid();
                setupGridProps(g);
                g.Children.Add(txblDot);
                brd.Child = g;
                wrpChars3.Children.Add(brd);

                brd = new Border();
                txblStroke = new TextBlock();
                txblStroke.Text = "_";
                setupTextBlockProps(txblStroke);
                setupBorderProps(brd);
                g = new Grid();
                setupGridProps(g);
                g.Children.Add(txblStroke);
                brd.Child = g;
                wrpChars3.Children.Add(brd);

                int row = 0;
                int col = 0;
                // Nummeric keyb.
                RowDefinition rd = new RowDefinition();
                rd.Height = new GridLength(60);
                grdNum.RowDefinitions.Add(rd);
                List<string> strs = new List<string>();
                strs.Add("'");
                strs.Add("@");
                strs.Add("#");
                strs.Add("$");
                strs.Add("%");
                strs.Add("&");
                strs.Add("/");
                strs.Add("(");
                strs.Add(")");
                for (int i = 1; i <= strs.Count; i++)
                {
                    brd = new Border();
                    TextBlock txbl = new TextBlock();
                    txbl.Text = strs[i - 1];
                    setupTextBlockProps(txbl);
                    setupBorderProps(brd);
                    g = new Grid();
                    setupGridProps(g);
                    g.Children.Add(txbl);
                    brd.Child = g;
                    Grid.SetRow(brd, row);
                    Grid.SetColumn(brd, col);
                    grdNum.Children.Add(brd);
                    col++;
                    if ((i % 3) == 0)
                    {
                        rd = new RowDefinition();
                        rd.Height = new GridLength(60);
                        grdNum.RowDefinitions.Add(rd);
                        row++;
                        col = 0;
                    }
                }
                brd = new Border();
                rd = new RowDefinition();
                rd.Height = new GridLength(60); ;
                grdNum.RowDefinitions.Add(rd);
                TextBlock txbl0 = new TextBlock();
                txbl0.Text = "*";
                setupTextBlockProps(txbl0);
                setupBorderProps(brd);
                g = new Grid();
                setupGridProps(g);
                g.Children.Add(txbl0);
                brd.Child = g;
                brd.Width = 110;
                Grid.SetRow(brd, row);
                Grid.SetColumn(brd, col);
                Grid.SetColumnSpan(brd, 2);
                grdNum.Children.Add(brd);
            }
            else
            {
                foreach (string str in keys1)
                {
                    brd = new Border();
                    TextBlock txbl = new TextBlock();
                    txbl.Text = str;
                    setupTextBlockProps(txbl);
                    setupBorderProps(brd);
                    g = new Grid();
                    setupGridProps(g);
                    g.Children.Add(txbl);
                    brd.Child = g;
                    wrpChars1.Children.Add(brd);
                }
                brd = new Border();
                txblShift = new TextBlock();
                txblShift.Text = "^";
                setupTextBlockProps(txblShift);
                setupBorderProps(brd);
                g = new Grid();
                setupGridProps(g);
                g.Children.Add(txblShift);
                brd.Child = g;
                wrpChars2.Children.Add(brd);
                foreach (string str in keys2)
                {
                    brd = new Border();
                    TextBlock txbl = new TextBlock();
                    txbl.Text = str;
                    setupTextBlockProps(txbl);
                    setupBorderProps(brd);
                    g = new Grid();
                    setupGridProps(g);
                    g.Children.Add(txbl);
                    brd.Child = g;
                    wrpChars2.Children.Add(brd);
                }

                brd = new Border();
                txblCroc = new TextBlock();
                txblCroc.Text = "<";
                setupTextBlockProps(txblCroc);
                setupBorderProps(brd);
                g = new Grid();
                setupGridProps(g);
                g.Children.Add(txblCroc);
                brd.Child = g;
                wrpChars3.Children.Add(brd);
                foreach (string str in keys3)
                {
                    brd = new Border();
                    TextBlock txbl = new TextBlock();
                    txbl.Text = str;
                    setupTextBlockProps(txbl);
                    setupBorderProps(brd);
                    g = new Grid();
                    setupGridProps(g);
                    g.Children.Add(txbl);
                    brd.Child = g;
                    wrpChars3.Children.Add(brd);
                }

                brd = new Border();
                txblComma = new TextBlock();
                txblComma.Text = ",";
                setupTextBlockProps(txblComma);
                setupBorderProps(brd);
                g = new Grid();
                setupGridProps(g);
                g.Children.Add(txblComma);
                brd.Child = g;
                wrpChars3.Children.Add(brd);

                brd = new Border();
                txblDot = new TextBlock();
                txblDot.Text = ".";
                setupTextBlockProps(txblDot);
                setupBorderProps(brd);
                g = new Grid();
                setupGridProps(g);
                g.Children.Add(txblDot);
                brd.Child = g;
                wrpChars3.Children.Add(brd);

                brd = new Border();
                txblStroke = new TextBlock();
                txblStroke.Text = "-";
                setupTextBlockProps(txblStroke);
                setupBorderProps(brd);
                g = new Grid();
                setupGridProps(g);
                g.Children.Add(txblStroke);
                brd.Child = g;
                wrpChars3.Children.Add(brd);

                int row = 0;
                int col = 0;
                // Nummeric keyb.
                RowDefinition rd = new RowDefinition();
                rd.Height = new GridLength(60);
                grdNum.RowDefinitions.Add(rd);
                for (int i = 1; i < 10; i++)
                {
                    brd = new Border();
                    TextBlock txbl = new TextBlock();
                    txbl.Text = i + "";
                    setupTextBlockProps(txbl);
                    setupBorderProps(brd);
                    g = new Grid();
                    setupGridProps(g);
                    g.Children.Add(txbl);
                    brd.Child = g;
                    Grid.SetRow(brd, row);
                    Grid.SetColumn(brd, col);
                    grdNum.Children.Add(brd);
                    col++;
                    if ((i % 3) == 0)
                    {
                        rd = new RowDefinition();
                        rd.Height = new GridLength(60);
                        grdNum.RowDefinitions.Add(rd);
                        row++;
                        col = 0;
                    }
                }
                brd = new Border();
                rd = new RowDefinition();
                rd.Height = new GridLength(60); ;
                grdNum.RowDefinitions.Add(rd);
                TextBlock txbl0 = new TextBlock();
                txbl0.Text = "0";
                setupTextBlockProps(txbl0);
                setupBorderProps(brd);
                g = new Grid();
                setupGridProps(g);
                g.Children.Add(txbl0);
                brd.Child = g;
                brd.Width = 110;
                Grid.SetRow(brd, row);
                Grid.SetColumn(brd, col);
                Grid.SetColumnSpan(brd, 2);
                grdNum.Children.Add(brd);
            }
        }

        private void setupGridProps(Grid grdToStyle)
        {
            grdToStyle.Background = new SolidColorBrush(Colors.Transparent);
            grdToStyle.Width = 50;
            grdToStyle.VerticalAlignment = System.Windows.VerticalAlignment.Center;
            grdToStyle.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;

            // Events
            grdToStyle.MouseDown += MouseButtonDownHandler;
            grdToStyle.MouseUp += MouseButtonUpHandler;
            grdToStyle.MouseLeave += MouseLeaveHandler;
            grdToStyle.MouseEnter += MouseEnterHandler;
        }

        private void setupTextBlockProps(TextBlock txblToStyle)
        {
            // TextBlock Styles
            txblToStyle.Background = new SolidColorBrush(Colors.Transparent);
            txblToStyle.FontSize = 40;
            txblToStyle.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
            txblToStyle.VerticalAlignment = System.Windows.VerticalAlignment.Center;
        }

        private void setupBorderProps(Border border)
        {
            // Border setup
            border.BorderBrush = new SolidColorBrush(Colors.LightBlue);
            border.BorderThickness = new Thickness(5);
            border.CornerRadius = new CornerRadius(4);
            border.Margin = new Thickness(3);
            border.Width = 50;
        }

        private void styleButtonClick_Grid(Grid grdToStyle)
        {
            grdToStyle.Background = new SolidColorBrush(Colors.Gray);
        }

        private void styleButtonUp_Grid(Grid grdToStyle)
        {
            grdToStyle.Background = new SolidColorBrush(Colors.Transparent);
        }

        private void MouseEnterHandler(object sender, MouseEventArgs h)
        {
            if (sender.GetType() == typeof(Grid))
            {
                styleButtonUp_Grid((Grid)sender);
            }
        }

        private void MouseLeaveHandler(object sender, MouseEventArgs h)
        {
            if (sender.GetType() == typeof(Grid))
            {
                styleButtonUp_Grid((Grid)sender);
            }
        }

        private void MouseButtonDownHandler(object sender, MouseButtonEventArgs e)
        {
            if (sender.GetType() == typeof(Grid))
            {
                Grid grdActual = (Grid)sender;
                styleButtonClick_Grid(grdActual);
            }
        }

        private void MouseButtonUpHandler(object sender, MouseButtonEventArgs e)
        {
            Grid grdActual = null;
            TextBlock txblActual = null;
            if (sender.GetType() == typeof(TextBlock))
            {
                txblActual = (TextBlock)sender;
            }
            else if (sender.GetType() == typeof(Grid))
            {
                grdActual = (Grid)sender;
                if (grdActual.Children[0].GetType() == typeof(TextBlock))
                {
                    txblActual = (TextBlock)grdActual.Children[0];
                }
            }

            if (grdActual != null)
            {
                styleButtonUp_Grid(grdActual);
            }
            if(txblActual != null)
            {
                if (txblActual == txblShift)
                {
                    toogleShift();
                }
                else if (txblActual == txblDelete)
                {
                    if (ControlToWriteToo.Text.Length > 0)
                    {
                        ControlToWriteToo.Text = (ControlToWriteToo.Text).Substring(0, ControlToWriteToo.Text.Length - 1);
                    }
                }
                else
                {
                    ControlToWriteToo.Text = ControlToWriteToo.Text + txblActual.Text;
                }
            }
        }
    }
}